/**
 * 函数式调用Loading加载效果
 * 使用
 * 步骤1: import useLoading from '@/components/base/use-loading'
 * 开启: 在某个声明周期函数中, 或函数中(并且调用)  const loadingInstance = useLoading()
 * 关闭: 使用useLoading()返回的实例对象(通过new出来的, 就是实例对象), 调用它原型上close()方法
 */

import LoadingVue from '@/components/base/Loading'
import Vue from 'vue'

/**
 * 创建Vue构造器
 * extend提供了一个能够构建组件的函数(也就是构造器). 主要用来服务与Vue.component
 * 使用这种函数式的构造组件的方法, 会更灵活一些
 * <p/>
 * 可以简单的理解为: 当模板中遇到组件名称作为标签的自定义元素时,
 * 会自动调用扩展实例构造器来生成组件实例, 并挂载到自定义元素上
 */
const LoadingConstructor = Vue.extend(LoadingVue)

// 这里也不能使用箭头函数来定义方法, 会出现this为指定问题不对
LoadingConstructor.prototype.close = function () {
  // this VueComponent {_uid: 8, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  console.log('close', this)
  if (this.$el && this.$el.parentNode) {
    this.$el.parentNode.removeChild(this.$el)
  }

  this.$destroy()
  this.loading = false
}
// ------------------------------------------------------ //
// 测试这个js文件的this指向问题  this = undefined
LoadingConstructor.prototype.testThis = () => {
  // testThis undefined
  console.log('testThis', this)
}
const instance = new LoadingConstructor()
instance.testThis()
// ------------------------------------------------------ //

const useLoading = () => {
  // 根据构造器创建 loading 实例对象
  const loadingInstance = new LoadingConstructor()
  // 并挂起到一个元素上 | $mount(elementSelector) 但是这里未指定元素, 它会被挂载到那个地方呢?
  const loadingEl = loadingInstance.$mount().$el
  document.body.appendChild(loadingEl)

  Vue.nextTick(() => {
    Vue.nextTick(() => {
      loadingInstance.loading = true
    })
  })
  return loadingInstance
}

export default useLoading
